package com.library.admin.controller;

import cn.hutool.core.util.StrUtil;
import com.library.admin.modules.user.bo.UserChangePasswordBO;
import com.library.admin.modules.user.bo.UserForgetPassword;
import com.library.admin.modules.user.entity.User;
import com.library.admin.modules.user.vo.UserInfoVO;
import com.library.admin.modules.user.vo.UserVO;
import com.library.admin.modules.user.bo.UserPage;
import com.library.admin.modules.user.bo.UserInsert;
import com.library.admin.modules.user.bo.UserUpdate;
import com.library.admin.modules.user.service.UserService;
import com.library.common.annotation.CurrentUser;
import com.library.common.constant.RedisKeyConstant;
import com.library.common.enums.ErrorCodeEnum;
import com.library.common.enums.StatusEnum;
import com.library.common.service.bo.CurrentLoginUser;
import com.library.common.util.RedisUtil;
import com.library.common.util.SmsUtil;
import com.library.logging.annotation.LogSys;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.library.common.response.Result;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;

import java.math.BigDecimal;
import java.util.Objects;
import java.util.UUID;


/**
 * @Author xyh
 * @Desc 用户表(User)表控制层
 * @Date 2023-09-10 10:51:00
 */

@Log4j2
@RestController
@RequestMapping("user")
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private RedisUtil redisUtil;


    /**
     * 分页查询列表
     *
     * @return 数据
     */
    @LogSys(value = "用户分页查询列表")
    @GetMapping("/list")
    public Result<IPage<UserVO>> queryByPage(@Valid UserPage page) {
        return Result.success(userService.queryByPage(page));
    }

    /**
     * 根据ID获取数据
     *
     * @return 单个用户表数据
     */
    @LogSys(value = "根据用户ID获取数据")
    @PostMapping("/queryById/{id}")
    public Result<UserVO> queryById(@PathVariable("id") Integer id) {
        return Result.success(userService.queryById(id));
    }


    /**
     * 用户注册
     *
     * @param param
     * @return 新增用户表数据
     */
    @LogSys(value = "用户注册")
    @PostMapping("/register")
    public Result insert(@Valid @RequestBody UserInsert param) {
        if (StrUtil.isEmpty(param.getUsername()) && StrUtil.isEmpty(param.getPassword())) {
            return Result.error("账号或密码不能为空！");
        }
        // 账号不能重复
        if (userService.getUserByUsername(param.getUsername()) != null) {
            return Result.error("用户名已存在，请重新填写用户名！");
        }
        String smsCodeCache = (String) redisUtil.get(RedisKeyConstant.SMS_VERIFY_REGISTER_CODE + param.getPhone());
        if (StrUtil.isEmpty(smsCodeCache) || param.getSmsCode() == null || !smsCodeCache.equalsIgnoreCase(String.valueOf(param.getSmsCode()))) {
            return Result.error("验证码为空或已失效，请重新获取验证码！");
        }

        boolean status = userService.insert(param);
        if (!status) {
            return Result.error("账号注册失败，请再次重试或联系管理员！");
        }
        return Result.success();
    }

    /**
     * 获取当前登录用户信息
     *
     * @param currentLoginUser
     * @return
     */
    @GetMapping("/info")
    public Result<?> getUserInfo(@CurrentUser CurrentLoginUser currentLoginUser) {
        if (currentLoginUser == null) {
            return Result.error("用户信息获取失败！");
        }
        UserInfoVO userInfo = null;
        try {
            userInfo = userService.getUserInfo(currentLoginUser);
        } catch (Exception e) {
            log.error("用户：{}, 获取当前登录用户信息失败：", currentLoginUser.getUsername(), e);
            return Result.error("获取当前登录用户信息失败!");
        }
        return Result.success(userInfo);
    }

    /**
     * 编辑用户表
     *
     * @return 编辑用户表数据
     */
    @LogSys(value = "编辑用户表数据")
    @PutMapping("/update")
    public Result update(@Valid @RequestBody UserUpdate param) {
        if (Objects.isNull(param.getId())) {
            return Result.error("ID不能为空");
        }
        boolean updateStatus = userService.update(param);
        if (!updateStatus) {
            return Result.error("用户手机号码重复，请修改！");
        }
        return Result.success();
    }

    /**
     * 删除用户表
     *
     * @return 删除用户表数据
     */
    @LogSys(value = "删除用户表数据")
    @DeleteMapping("/delete/{id}")
    public Result deleteById(@PathVariable("id") Integer id) {
        userService.deleteById(id);
        return Result.success();
    }

    /**
     * 修改用户登录密码
     *
     * @param bo
     * @return
     */
    @LogSys(value = "修改用户登录密码")
    @PostMapping("/change/password")
    public Result<?> updatePassword(@RequestBody @Valid UserChangePasswordBO bo, @CurrentUser CurrentLoginUser currentLoginUser) {
        if (StrUtil.isBlank(bo.getNewPassword()) || StrUtil.isBlank(bo.getConfirmNewPassword())) {
            return Result.error("密码或确认密码不能为空");
        }
        if (!bo.getConfirmNewPassword().equals(bo.getNewPassword())) {
            return Result.error("密码与确认密码不同，请检查是否一致");
        }
        userService.changePassword(bo, currentLoginUser);
        return Result.success();
    }

    /**
     * 重置密码
     *
     * @param param
     * @return
     */
    @LogSys(value = "重置密码")
    @PostMapping("/forget/password")
    public Result resettingPassword(@Valid @RequestBody UserForgetPassword param) {
        User user = userService.getUserByPhone(param.getPhone());
        if (user == null) {
            return Result.error("用户获取失败，请检查手机号是否正确！");
        }
        if (!user.getUsername().equals(param.getUsername())) {
            return Result.error("账号不正确，请填写正确的登录账号！");
        }
        if (StatusEnum.STOP.equals(user.getStatus())) {
            return Result.error(ErrorCodeEnum.USER_STOP.getCode(), "该帐号已被停用，无法重置密码");
        }
        String smsCodeCache = (String) redisUtil.get(RedisKeyConstant.SMS_VERIFY_FORGET_CODE + param.getPhone());
        if (!userService.checkCode(smsCodeCache, param.getVerifyCode())) {
            return Result.error(ErrorCodeEnum.VERIFY_CODE.getCode(), "验证码不正确或已过期");
        }
        userService.forgetPassword(user, param);
        return Result.success("初始密码已通过短信方式发送到您的手机，请注意查收！");
    }

    /**
     * 账号充值
     *
     * @param param
     * @return
     */
    @LogSys(value = "账号充值")
    @PostMapping("/invest/money")
    public Result<?> investMoneyByUserId(@Valid @RequestBody UserUpdate param) {
        if (param.getBalance() != null) {
            if (param.getBalance().compareTo(BigDecimal.ZERO) == -1 ||
                    param.getBalance().compareTo(BigDecimal.ZERO) == 0) {
                return Result.error("充值金额不能为0或负数");
            }
        }
        userService.setInvestMoney(param);
        return Result.success();
    }

    /**
     * 更新用户基础配置
     *
     * @param param
     * @param currentLoginUser
     * @return
     */
    @PutMapping("/update/baseSetting")
    public Result<?> updateBaseSetting(@Valid @RequestBody UserUpdate param, @CurrentUser CurrentLoginUser currentLoginUser) {
        param.setId(currentLoginUser.getUserId());
        param.setUsername(currentLoginUser.getUsername());
        userService.update(param);
        return Result.success();
    }

}
